﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Scaffold
{
	public class Config
	{
		public static Config config = new Config();
		string fileName = "config.xml";
		public Config()
		{
			if (!Load())
			{
			}
		}
		public Config(Config old)
		{
			var p = old.GetType().GetProperties();
			foreach (var item in p)
			{
				var oldVal = item.GetValue(old);
				this.GetType().GetProperty(item.Name).SetValue(this, oldVal);
			}
		}
		public bool Save()
		{
			XmlDocument doc = new XmlDocument();
			XmlNode root = doc.CreateElement("root");
			doc.AppendChild(root);
			var p = GetType().GetProperties();
			foreach (var item in p)
			{
				XmlElement n = doc.CreateElement(item.Name);
				if (item.PropertyType != typeof(Point))
					n.SetAttribute("value", item.GetValue(this).ToString());
				else
					n.SetAttribute("value", new PointConverter().ConvertToString(item.GetValue(this)));
				root.AppendChild(n);
			}
			try
			{
				doc.Save(fileName);
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message);
				Console.WriteLine(e.StackTrace);
				return false;
			}
			return true;
		}
		public bool Load()
		{
			try
			{
				XmlDocument doc = new XmlDocument();
				doc.Load(fileName);
				var p = GetType().GetProperties();
				XmlNode root = doc.FirstChild;
				foreach (var item in p)
				{
					var t = root[item.Name];
					if (item.PropertyType == typeof(string))
						item.SetValue(this, t.GetAttribute("value"));
					else if (item.PropertyType == typeof(int))
						item.SetValue(this, Convert.ToInt32(t.GetAttribute("value")));
					else if (item.PropertyType == typeof(double))
						item.SetValue(this, Convert.ToDouble(t.GetAttribute("value")));
					else if (item.PropertyType == typeof(Point))
						item.SetValue(this, new PointConverter().ConvertFromString(t.GetAttribute("value")));
					else if (item.PropertyType == typeof(float))
						item.SetValue(this, float.Parse(t.GetAttribute("value")));
					else if (item.PropertyType == typeof(bool))
						item.SetValue(this, bool.Parse(t.GetAttribute("value")));
					else if (item.PropertyType == typeof(ushort))
						item.SetValue(this, ushort.Parse(t.GetAttribute("value")));
					else if (item.PropertyType == typeof(byte))
						item.SetValue(this, byte.Parse(t.GetAttribute("value")));
					else
						throw new Exception("\n\n!!! Not Implement Type Convertion When Reflect !!!\n\n");
				}
			}
			catch (FileNotFoundException)
			{
				return false;
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message);
				Console.WriteLine(e.StackTrace);
				return false;
			}
			return true;
		}
		#region 写需要保存的字段。必须以属性的形式
		public float XMCPerPX { get; set; }
		public float YMCPerPX { get; set; }
		public float MCPerDG { get; set; }
		public float MCPerMM { get; set; }

		//回原点速度
		public int HMVMin { get; set; }
		public int HMVMax { get; set; }
		public float HMTacc { get; set; }

		//回起始点速度
		public int SPVMin { get; set; }
		public int SPVMax { get; set; }
		public float SPTacc { get; set; }

		//切割速度
		public int CTVMin { get; set; }
		public int CTVMax { get; set; }
		public float CTTacc { get; set; }

		//空刀速度
		public int EVMin { get; set; }
		public int EVMax { get; set; }
		public float ETacc { get; set; }


		public float AngOff { get; set; }

		public Point Offset { get; set; }
		public double CuttingWidth { get; set; }
		public double CuttingHeight { get; set; }

		public Point OffsetAfterSpin { get; set; }
		public Point StartPoint { get; set; }
		public string ImgLocation { get; set; }
		public Point Pt1 { get; set; }
		public Point Pt2 { get; set; }
		public Point Pt3 { get; set; }
		public Point Pt4 { get; set; }
		public int TimePerCut { get; set; }
		public int TotalTime { get; set; }
		public int CutCount { get; set; }
		public double PXpMM { get; set; }
		public double KnfThk { get; set; }
		public double ExtraX { get; set; }
		public double ExtraY { get; set; }
		public int ChessWid { get; set; }
		public int ChessHei { get; set; }
		public int SlowSpeed { get; set; }
		public int SlowTime { get; set; }
		public int ImgWid { get; set; }
		public int ImgHei { get; set; }

		public double BigWid1 { get; set; }
		public double BigWid2 { get; set; }
		public double BigWid3 { get; set; }
		public double BigWid4 { get; set; }
		public double BigWid5 { get; set; }
		public double BigWid6 { get; set; }
		public double BigWid7 { get; set; }
		public double BigWid8 { get; set; }
		public double BigHei1 { get; set; }
		public double BigHei2 { get; set; }
		public double BigHei3 { get; set; }
		public double BigHei4 { get; set; }
		public double BigHei5 { get; set; }
		public double BigHei6 { get; set; }
		public double BigHei7 { get; set; }
		public double BigHei8 { get; set; }


		#endregion
		/// <summary>
		/// 返回包含刀片厚度在内的切割宽度像素数
		/// </summary>
		public int GetCuttingHeightIncludingKnf()
		{
			return (int)((CuttingHeight + KnfThk) * PXpMM);
		}
		/// <summary>
		/// 返回包含刀片厚度在内的切割高度像素数
		/// </summary>
		public int GetCuttingWidthIncludeingKnf()
		{
			return (int)((CuttingWidth + KnfThk) * PXpMM);
		}

		/// <summary>
		/// 返回X方向额外的切割距离（像素）
		/// </summary>
		public int GetExtraXPX()
		{
			return (int)(ExtraX * PXpMM);
		}

	}
}
